#pragma once
#include"preCmpH.h"
#include"UIUtilities.h"
#include"UIImage.h"
#include"UIEvent.h"
#include"UIManagerControlInterface.h"

BEGIN_NAMESPACE(ui_manager)
class UIManager;
typedef std::shared_ptr<UIManager> UIManagerSharedPtr;
BEGIN_NAMESPACE(ui_controls)

class UIControlContainer;
typedef std::shared_ptr<UIControlContainer> UIControlContainerPtr;

class UIControl;
typedef std::shared_ptr<UIControl> UIControlPtr; // Shared pointer to manage dynamic UIControl objects

// Class to be used as a base for UI element classes
class UIControl
{
public:
//=====================================
// Constructors, Destructor, Operators
//=====================================
	//========== Description ==========
	//PURPOSE : Construct Object
	//REQUIRE : Nothing
	//PROMISE : Initialize object with default values
	UIControl();
	virtual ~UIControl();
//==========
// Setters
//==========

	//========== Description ==========
	//PURPOSE : Set the position of the control
	//REQUIRE : UIPoint with valid information
	//PROMISE : Set position to the on specified
	virtual void setPosition(UIPoint pos);
	//========== Description ==========
	//PURPOSE : Set the size of the control
	//REQUIRE : UISize with valid information
	//PROMISE : Set size to the one specified
	virtual void setSize(UISize size);
	//========== Description ==========
	//PURPOSE : Set the background of the control
	//REQUIRE : UIImage reference with valid information
	//PROMISE : Set background image to the one specified
	virtual void setBackground(ui_manager::ui_graphics::UIImage* img);
	//========== Description ==========
	//PURPOSE : Establish if the control is visible
	//REQUIRE : A true or false value
	//PROMISE : Set the visibility truth to the one specified
	virtual void setVisible(bool is_visible);
	//========== Description ==========
	//PURPOSE : Set the name of the control
	//REQUIRE : A nonempty string
	//PROMISE : Set the name to the one specified
	virtual void setName(std::string name);
	//========== Description ==========
	//PURPOSE : Set the parent of the control
	//REQUIRE : A non-null UIControlPtr
	//PROMISE : Set the parent to the one specified
	virtual void setParent(UIControlContainer& parent);
//==========
// Getters
//==========

	//========== Description ==========
	//PURPOSE : Get the position of the control
	//REQUIRE : Nothing
	//PROMISE : Return the position by value
	virtual UIPoint getPosition()const;
	//========== Description ==========
	//PURPOSE : Get the size of the control
	//REQUIRE : Nothing
	//PROMISE : Return the size by value
	virtual UISize getSize()const;
	//========== Description ==========
	//PURPOSE : Get the background image of the control
	//REQUIRE : Nothing
	//PROMISE : Return const address of the image
	virtual ui_manager::ui_graphics::UIImage& getBackground()const;
	//========== Description ==========
	//PURPOSE : Establish if the control is visible
	//REQUIRE : Nothing
	//PROMISE : Return true or false depending on the visibility of the control
	virtual bool isVisible()const;
	//========== Description ==========
	//PURPOSE : Get the name of the control
	//REQUIRE : Nothing
	//PROMISE : Return a string either contains the name of the control or is empty
	virtual std::string getName()const;
	//========== Description ==========
	//PURPOSE : Establish if the control has a parent
	//REQUIRE : Nothing
	//PROMISE : Return true or false depending if the control has or not a parent
	virtual bool hasParent()const;
	//========== Description ==========
	//PURPOSE : Get the parent of the control
	//REQUIRE : hasParent() to be true
	//PROMISE : Return const address of the parent
	virtual const UIControlContainer& getParent()const;
	//========== Description ==========
	//PURPOSE : Handle events passed to the control
	//REQUIRE : UIEvent object with valid information
	//PROMISE : Handle event and post it to children and sibling is necessary
	virtual void HandleEvent(ui_events::UIEvent ui_event);
	//========== Description ==========
	//PURPOSE : Binds the control a UIManager
	//REQUIRE : UIManager reference to an initialized object and a call to the base class BoundBy
	//PROMISE : Binds the control to the specified manager
	virtual void BoundBy(UIManager& manager, bool is_component);
	//========== Description ==========
	//PURPOSE : None
	//REQUIRE : Nothing
	//PROMISE : Nothing
	virtual void UnboundBy(UIManager& manager);
protected:
	const UIControl& getFocus();
	void setFocus(UIControl& focus);

	UIPoint pos_;			// holds the position
	UISize size_;			// holds the size
	bool visible_;			// specifies visibility
	ui_manager::ui_graphics::UIImage* background_;// holds the background image
	std::string name_;			// specifies the name	
	bool focused_;		// specifies if focused
	bool bound_;			// specifies if bound
	UIManagerControlInterface mcInterface_;

private:
	UIControlContainer* parent_;	// hold the parent
	UIControl* focus_;		// holds the focused control
	
	//========== Description ==========
	//PURPOSE : Render`s the control
	//REQUIRE : UIRenderMsg object with valid information
	//PROMISE : Perform the rendering
	virtual void Render(UIPoint parentPosistion);
	

	//========== Description ==========
	//PURPOSE : Test the invariants
	//REQUIRE : Nothing
	//PROMISE : Stop application and post error report
	void TestInvariant() const;

	friend class UIManager;
};

END_NAMESPACE // UI controls
END_NAMESPACE // UI manager